import pygame
import sys
import os
from typing import List
from .music_player import MusicPlayer

# 添加父目录到系统路径
current_dir = os.path.dirname(os.path.abspath(__file__))
parent_dir = os.path.dirname(current_dir)
sys.path.append(parent_dir)

from constant import Setting 
from .button import Button

class CharacterSelectUI:
    """游戏角色选择界面"""
    
    def __init__(self, characters: List):
        """
        初始化角色选择界面
        :param characters: 角色对象列表，每个角色应包含name和image_path属性
        """
        pygame.init()
        self.settings = Setting()
        self.root_dir = parent_dir  # 项目根目录
        
        # 屏幕设置
        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height)
        )
        pygame.display.set_caption(f"{self.settings.screen_title} - 选择角色")
        
        # 角色数据
        self.characters = characters  # 接收外部传入的角色类实例
        self.selected_index = 0  # 默认选中第一个角色
        
        # 加载资源
        self.background = self._load_background()
        self.character_images = self._load_character_images()
        
        # 计算布局
        self._calculate_positions()
        
        # 状态控制
        self.running = True
        self.selected_character = None  # 最终选择的角色

        # 加载标题背景图片
        self.title_bg_image = self._load_title_background()
        
        #music_player
        self.music_player = MusicPlayer()

        # 创建确认按钮
        self.confirm_button = self._create_confirm_button()
    
    def _load_title_background(self):
        """加载标题的背景图片"""
        try:
            # 从配置获取标题背景图路径
            title_bg_path = os.path.join(self.root_dir, self.settings.title_images_path["select_title"])
            title_bg = pygame.image.load(title_bg_path).convert_alpha()
            
            # 缩放标题背景图（宽度为屏幕的60%）
            target_width = int(self.settings.screen_width * 0.6)
            scale_ratio = target_width / title_bg.get_width()
            target_height = int(title_bg.get_height() * scale_ratio)
            
            return pygame.transform.scale(title_bg, (target_width, target_height))
        except FileNotFoundError:
            print(f"【错误】未找到标题背景图: {title_bg_path}")
            # 加载失败时使用半透明金色背景
            fallback_surf = pygame.Surface((int(self.settings.screen_width * 0.6), 100), pygame.SRCALPHA)
            fallback_surf.fill((255, 215, 0, 128))  # 金色半透明
            return fallback_surf

    def _create_confirm_button(self):
        """创建右下角的确认按钮"""
        start_btn_img_path = os.path.join(
            self.root_dir, 
            self.settings.button_images_path["start_ui_button"]
        )
        # 按钮位置：右下角，留出边距
        button_x = self.settings.screen_width - self.settings.btn_width - 50
        button_y = self.settings.screen_height - self.settings.btn_height - 50
        
        return Button(
            x=button_x,
            y=button_y,
            text="start", 
            settings=self.settings,
            action=self._on_confirm,
            image_path=start_btn_img_path
        )

    def _on_confirm(self):
        """确认按钮点击事件"""
        if self.characters:  # 确保有角色可供选择
            print(f"确认选择角色: {self.characters[self.selected_index].name}")
            self.selected_character = self.characters[self.selected_index]
            self.running = False

    def _load_background(self):
        """加载角色选择界面背景图"""
        try:
            # 从配置中获取角色选择背景图路径
            bg_path = os.path.join(self.root_dir, self.settings.images_path["select_background"])
            background = pygame.image.load(bg_path).convert()
            return pygame.transform.scale(
                background, (self.settings.screen_width, self.settings.screen_height)
            )
        except FileNotFoundError:
            print(f"【错误】未找到角色选择背景图: {bg_path}")
            # 背景图加载失败时使用默认颜色
            surface = pygame.Surface((self.settings.screen_width, self.settings.screen_height))
            surface.fill(self.settings.bg_color_character)
            return surface
    
    def _load_character_images(self):
        """加载所有角色的图片"""
        character_images = []
        for char in self.characters:
            try:
                # 加载原始图片
                img_path = os.path.join(self.root_dir, char.image_path)
                img = pygame.image.load(img_path).convert_alpha()
                
                # 保存原始和缩放后的图片（正常大小和选中大小）
                normal_size = (200, 250)  # 角色图片正常尺寸
                selected_size = (250, 300)  # 选中时的放大尺寸
                
                normal_img = pygame.transform.scale(img, normal_size)
                selected_img = pygame.transform.scale(img, selected_size)
                
                character_images.append({
                    "normal": normal_img,
                    "selected": selected_img,
                    "normal_rect": normal_img.get_rect(),
                    "selected_rect": selected_img.get_rect()
                })
            except FileNotFoundError:
                print(f"【错误】未找到角色图片: {char.image_path}")
                # 角色图片加载失败时使用占位图
                normal_img = pygame.Surface((120, 180), pygame.SRCALPHA)
                normal_img.fill((100, 100, 100, 200))
                selected_img = pygame.Surface((160, 240), pygame.SRCALPHA)
                selected_img.fill((100, 100, 100, 200))
                
                character_images.append({
                    "normal": normal_img,
                    "selected": selected_img,
                    "normal_rect": normal_img.get_rect(),
                    "selected_rect": selected_img.get_rect()
                })
        return character_images
    
    def _calculate_positions(self):
        """计算角色图片和名字的位置（排列在地面上）"""
        # 计算角色展示区域的总宽度
        total_width = self.settings.screen_width * 0.8  # 使用屏幕80%宽度
        spacing = total_width / (len(self.characters) + 1)  # 角色间的间距
        
        # 计算地面位置（假设地面在屏幕底部三分之一处）
        ground_y = self.settings.screen_height * 0.65
        
        self.character_positions = []
        
        for i in range(len(self.characters)):
            # 计算x坐标，平均分布
            x = self.settings.screen_width * 0.1 + spacing * (i + 1)
            
            # 计算图片底部对齐到地面
            normal_y = ground_y - self.character_images[i]["normal_rect"].height
            selected_y = ground_y - self.character_images[i]["selected_rect"].height
            
            # 计算名字位置（图片下方居中）
            name_font = self.settings.font_menu
            name_text = name_font.render(self.characters[i].name, True, self.settings.color_white)
            name_rect = name_text.get_rect(
                centerx=x, 
                top=ground_y + 10  # 地面上方10px
            )
            
            self.character_positions.append({
                "normal_x": x,
                "normal_y": normal_y,
                "selected_x": x,
                "selected_y": selected_y,
                "name_text": name_text,
                "name_rect": name_rect
            })
    
    def _handle_mouse_selection(self, pos):
        """处理鼠标选择角色"""
        for i in range(len(self.character_positions)):
            # 获取当前角色的碰撞区域（考虑选中和未选中两种状态）
            if i == self.selected_index:
                rect = self.character_images[i]["selected_rect"].copy()
                rect.centerx = self.character_positions[i]["selected_x"]
                rect.centery = self.character_positions[i]["selected_y"] + \
                              self.character_images[i]["selected_rect"].height // 2
            else:
                rect = self.character_images[i]["normal_rect"].copy()
                rect.centerx = self.character_positions[i]["normal_x"]
                rect.centery = self.character_positions[i]["normal_y"] + \
                              self.character_images[i]["normal_rect"].height // 2
            
            # 检测鼠标是否点击了该角色
            if rect.collidepoint(pos):
                self.selected_index = i
                return True  # 表示点击了角色，不再处理其他
        return False  # 表示没有点击角色
    
    def _handle_keyboard_navigation(self, key):
        """处理键盘导航（左右箭头键）"""
        if key == pygame.K_LEFT:
            self.selected_index = (self.selected_index - 1) % len(self.characters)
        elif key == pygame.K_RIGHT:
            self.selected_index = (self.selected_index + 1) % len(self.characters)
        elif key == pygame.K_RETURN:  # 回车键确认选择
            self._on_confirm()  # 复用确认按钮的逻辑
    
    def handle_events(self):
        """处理用户输入事件"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
                self.selected_character = None  # 退出时不选择任何角色
            else:
                # 先让按钮处理事件（优先级高于角色选择）
                button_clicked = self.confirm_button.handle_event(event)
                
                # 如果按钮没有处理事件，再处理角色选择
                if not button_clicked:
                    if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                        self._handle_mouse_selection(event.pos)
                    elif event.type == pygame.KEYDOWN:
                        self._handle_keyboard_navigation(event.key)
                        if event.key == pygame.K_ESCAPE:  # ESC键返回
                            self.running = False
                            self.selected_character = None
    
    def draw(self):
        """绘制界面元素"""
        # 绘制背景
        self.screen.blit(self.background, (0, 0))
        
        # 绘制标题背景图片
        title_bg_x = (self.settings.screen_width - self.title_bg_image.get_width()) // 2
        title_bg_y = 30  # 标题背景的y坐标
        self.screen.blit(self.title_bg_image, (title_bg_x, title_bg_y))
        
        # 绘制标题文字（在背景图上方居中）
        title_text = self.settings.font_title.render("choose character", True, self.settings.color_white)
        title_rect = title_text.get_rect(
            centerx=self.settings.screen_width // 2,
            centery=title_bg_y + self.title_bg_image.get_height() // 2
        )
        self.screen.blit(title_text, title_rect)
        
        # 绘制操作提示
        hint_text = self.settings.font_small.render(
            "使用方向键或鼠标选择角色，按回车或点击按钮确认", 
            True, self.settings.color_white
        )
        hint_rect = hint_text.get_rect(centerx=self.settings.screen_width // 2, y=title_bg_y + self.title_bg_image.get_height() + 20)
        self.screen.blit(hint_text, hint_rect)
        
        # 绘制所有角色
        for i in range(len(self.characters)):
            if i == self.selected_index:
                self.screen.blit(
                    self.character_images[i]["selected"],
                    (
                        self.character_positions[i]["selected_x"] - 
                        self.character_images[i]["selected_rect"].width // 2,
                        self.character_positions[i]["selected_y"]
                    )
                )
            else:
                self.screen.blit(
                    self.character_images[i]["normal"],
                    (
                        self.character_positions[i]["normal_x"] - 
                        self.character_images[i]["normal_rect"].width // 2,
                        self.character_positions[i]["normal_y"]
                    )
                )
            self.screen.blit(self.character_positions[i]["name_text"], self.character_positions[i]["name_rect"])
        
        # 绘制确认按钮
        self.confirm_button.draw(self.screen)
        
        # 更新屏幕
        pygame.display.flip()
    
    
    def run(self):
        """运行角色选择界面主循环"""
        clock = pygame.time.Clock()
        
        while self.running:
            clock.tick(self.settings.fps)
            self.handle_events()
            self.draw()
            self.music_player.play_music("start")
        # 只在确认选择后才退出pygame，避免影响后续界面
        if self.selected_character:
            pygame.display.quit()  # 只关闭显示，不退出整个pygame
        else:
            pygame.quit()
            
        return self.selected_character

# 测试代码
if __name__ == "__main__":
    # 测试用的角色类（实际使用时会从外部导入）
    class TestCharacter:
        def __init__(self, name, image_path):
            self.name = name
            self.image_path = image_path
    
    # 创建测试角色
    test_characters = [
        TestCharacter("charactor1", "image/test_charactor.png"),
        TestCharacter("charactor2", "image/test_charactor.png"),
        TestCharacter("charactor3", "image/test_charactor.png"),
        TestCharacter("charactor4", "image/test_charactor.png"),
        TestCharacter("charactor5", "image/test_charactor.png")
    ]
    
    # 运行角色选择界面
    character_select = CharacterSelectUI(test_characters)
    selected = character_select.run()
    
    if selected:
        print(f"选择了角色: {selected.name}")
    else:
        print("未选择角色，返回上一级")
    sys.exit()